package cn.ad.server.web.spring.service.actions;

import cn.ad.server.common.utils.BrowserUtils;
import cn.ad.server.common.utils.IPUtils;
import cn.ad.server.domain.enumration.OS;
import cn.ad.server.web.log.IAdServerLogger;
import cn.ad.server.web.spring.model.BidAdRequest;
import cn.ad.server.web.spring.model.BidAdResponse;
import cn.ad.server.web.spring.model.Exchange;
import cn.ad.server.web.spring.model.adview.AdViewBidRequest;
import cn.ad.server.web.spring.model.gdt.*;
import cn.ad.server.web.spring.service.actions.context.BidContext;
import cn.ad.server.web.spring.service.actions.context.IPContext;
import cn.ad.server.web.spring.service.biz.GDTImpressionMatchService;
import cn.ad.server.biz.internal.AdService;
import cn.ad.server.domain.IPDetail;
import cn.ad.server.domain.ad.AreaPlatformMap;
import cn.ad.server.domain.enumration.Gender;
import cn.ad.server.domain.enumration.MUniqueType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * 广点通Adx接入请求处理
 * 
 * @author Wu Chengjun
 *
 */
@Component("action-bid-gdt")
public class GDTAdRequestAction extends BidAdRequestAction {

	static Logger LOGGER = LoggerFactory.getLogger(GDTAdRequestAction.class);

	@Autowired
	private GDTImpressionMatchService gdtImpressionHandler;

	@Autowired
	private IAdServerLogger loggerService;

	@Autowired
	private AdService adService;

	/*
	 * (non-Javadoc)
	 * 
	 * @see cn.ad.server.web.spring.service.actions.
	 * BidAdRequestAction#doRequest(cn.ad.server.web.spring.
	 * model.BidAdRequest)
	 */
	@Override
	BidAdResponse doRequest(BidAdRequest request) {
		try {
			GDTBidRequest req = (GDTBidRequest) request;
			BidContext context = initBidData(req);
			return doProcess(req, context);
		} finally {
			adService.unbond();
		}
	}

	public BidAdResponse doProcess(BidAdRequest bidAdRequest, BidContext bidContext) {

		GDTBidRequest gdtBidRequest = (GDTBidRequest) bidAdRequest;
		GDTBidResponse gdtBidResponse = new GDTBidResponse();

		// 处理参数解析异常的处理
		if (bidContext == null) {
			if (bidAdRequest != null) {
				gdtBidResponse.setRequest_id(gdtBidRequest.getId());
			}

			// gdtBidRequest.setNbr(AdViewBidResponse.NOT_BID_REASON.INVALID_REQUEST.getValue());
			return gdtBidResponse;
		}

		gdtBidResponse.setRequest_id(gdtBidRequest.getId());
		List<GDTSeatBid> seatBidList = new ArrayList<GDTSeatBid>();

		List<GDTImpression> impressions = gdtBidRequest.getImpressions();

		for (int i = 0; i < impressions.size(); i++) {

			BidContext impBidContext = (BidContext) bidContext.clone();
			List<GDTBid> bids = new ArrayList<GDTBid>();
			try {
				GDTBid bid = gdtImpressionHandler.handler(impressions.get(i), impBidContext);
				if (bid != null) {
					bids.add(bid);
					GDTSeatBid seatBid = new GDTSeatBid();
					seatBid.setImpression_id(impressions.get(i).getId());
					seatBid.setBids(bids);
					seatBidList.add(seatBid);
				}
			} catch (Exception e) {
				LOGGER.error("There a exception at ImpressioneHandler, reason: {}, \n BidContext: \n {}",
						e.getMessage(), impBidContext.toString(), e);
			} finally {
				// FIXME 记录日志，将日志处理放到RequestHandler层
				loggerService.logAdBidRequest(impBidContext);
			}

		}

		gdtBidResponse.setSeat_bids(seatBidList);

		// if (gdtBidRequest.getUser() != null &&
		// gdtBidRequest.getUser().getAudience_ids() != null) {
		// if (gdtBidRequest.getUser().getAudience_ids().contains(2890056)) {
		// LOGGER.info("gdtBidRequest------------ - {}", gdtBidRequest);
		// LOGGER.info("gdtBidResponse------ {}", gdtBidResponse);
		// }
		// }

		return gdtBidResponse;
	}

	public BidContext initBidData(BidAdRequest bidAdRequest) {
		BidContext bidContext = new BidContext();
		if (bidAdRequest == null)
			return null;
		bidContext.setChannel(bidAdRequest.getChannelID());
		bidContext.setAdxType(Integer.parseInt(Exchange.GDT.getValue()));
		bidContext.setRequestTimestamp(System.currentTimeMillis());
		bidContext.setServerId(IPUtils.getHostName());

		GDTBidRequest gdtBidRequest = (GDTBidRequest) bidAdRequest;
		bidContext.setFeeType("cpm");
		bidContext.setTransactionType(AdViewBidRequest.AT.SECOND.ordinal());
		bidContext.setBidId(gdtBidRequest.getId());
		bidContext.setIp(gdtBidRequest.getIp());
		bidContext.setAreaCode(gdtBidRequest.getArea_code());

		if (gdtBidRequest.getUser() != null)
			bidContext.setUserDmpId(gdtBidRequest.getUser().getAudience_ids());

		// Device信息
		GDTDevice device = gdtBidRequest.getDevice();
		if (device != null) {

			bidContext.setUa(device.getUser_agent());
			this.convertIPDetail(bidContext.getIp(), bidContext);
			bidContext.setIdfa(device.getIdfa());
			bidContext.setLanguage(device.getLanguage());
			bidContext.setAnid(device.getAndroid_id());
			bidContext.setModal(device.getBrand_and_model());

			boolean init = true;

			if (StringUtils.hasText(device.getIdfa())) {
				bidContext.setIdfa(device.getIdfa());
				if (init) {
					bidContext.setMuniqueType(MUniqueType.IDFA.getValue());
					bidContext.setMuniqueId(device.getIdfa());
					init = false;
				}
			}

			// 操作系统
			if (device.getOs() != null) {
				String os = device.getOs().name();
				if (os != null) {
					if (os.toLowerCase().contains("ios")) {
						bidContext.setOs(OS.IOS.getValue());
					} else if (os.toLowerCase().contains("android")) {
						bidContext.setOs(OS.ANDROID.getValue());
					} else if (os.toLowerCase().contains("windows")) {
						bidContext.setOs(OS.WINDOWS.getValue());
					} else {
						bidContext.setOs(OS.UNKNOWN.getValue());
					}
				}
			}
			bidContext.setOsVersion(device.getOs_version());
			if(device.getConnection_type() != null) {
				bidContext.setConnType(device.getConnection_type().value());
				
			}
			int deviceType = 0;
			if (device.getDevice_type() == GDTDeviceType.DEVICETYPE_MOBILE) {
				if (device.getOs() == GDTOs.OS_IOS) {
					deviceType = 1;
				} else if (device.getOs() == GDTOs.OS_ANDROID) {
					deviceType = 2;
				} else if (device.getOs() == GDTOs.OS_WINDOWS) {
					deviceType = 4;
				}
			} else if (device.getDevice_type() == GDTDeviceType.DEVICETYPE_PAD) {
				if (device.getOs() == GDTOs.OS_IOS) {
					deviceType = 3;
				} else if (device.getOs() == GDTOs.OS_ANDROID) {
					deviceType = 5;
				}
			} else if (device.getDevice_type() == GDTDeviceType.DEVICETYPE_PC) {
				deviceType = 7;
			}

			bidContext.setDeviceType(deviceType);
			bidContext.setScreenDensity(device.getDpi());
			bidContext.setScreenWidth(device.getScreen_width());
			bidContext.setScreenHeight(device.getScreen_height());
			if(device.getCarrier() != null)
				bidContext.setMobOps(device.getCarrier().value());

			GDTGeo geo = gdtBidRequest.getGeo();
			if (geo != null) {
				float lati = new BigDecimal(geo.getLatitude()).divide(new BigDecimal(1000000)).floatValue();
				float longitude = new BigDecimal(geo.getLongitude()).divide(new BigDecimal(1000000)).floatValue();
				bidContext.setLatitude(lati);
				bidContext.setLongitude(longitude);
			}
		}

		GDTApp app = gdtBidRequest.getApp();
		if (app != null) {
			bidContext.setAppId(app.getApp_bundle_id());
		}

		bidContext.setBrowser(BrowserUtils.getBrowser(bidContext.getUa()));
		GDTUser user = gdtBidRequest.getUser();
		if (user != null) {
			bidContext.setUserId(user.getId());
			// 用户性别
			String gender = user.getUser_demographic() == null ? "" : user.getUser_demographic().getGender().toString();
			if ("GENDER_MALE".equals(gender)) {
				bidContext.setGender(Gender.MALE.getValue());
			} else if ("GENDER_FEMALE".equals(gender)) {
				bidContext.setGender(Gender.FEMALE.getValue());
			} else {
				bidContext.setGender(Gender.UNKNOWN.getValue());
			}
			if (user.getUser_demographic() != null) {
				bidContext.setAgeLow(user.getUser_demographic().getAge_low());
				bidContext.setAgeHigh(user.getUser_demographic().getAge_high());
			}
		}

		return bidContext;
	}

	void convertIPDetail(String ip, BidContext bidContext) {
		IPDetail ipDetail = null;
		if (!StringUtils.isEmpty(ip)) {
			ipDetail = IPContext.instance().getIPDetail(IPUtils.convertIPToLong(bidContext.getIp()));
			if (ipDetail != null) {
				bidContext.setCountryId(ipDetail.getCountryId());
				bidContext.setStateId(ipDetail.getStateId());
				bidContext.setCityId(ipDetail.getCityId());
				bidContext.setDistrictId(ipDetail.getDistrictId());
			}
		}

		// ip为空，或者ip异常，解析出错，走地域码的逻辑
		if (StringUtils.isEmpty(ip) || ipDetail == null) {
			AreaPlatformMap apm = adService.fetchAreaPlatformMapByTargetId(bidContext.getAreaCode());
			if (apm != null) {
				if (apm.getType() == 1)
					bidContext.setStateId(apm.getAreaId());
				else if (apm.getType() == 2)
					bidContext.setCityId(apm.getAreaId());
			}

		}

	}

}
